#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/un.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>

#define UNIXDG_PATH "/tmp/unix_"
#define UNIXDG_PATH2 UNIXDG_PATH "save.dg"
#define UNIXDG_PATH3 UNIXDG_PATH "bck.dg"
#define FILE_PATH1 "/mnt/UDISK/FILE_PATH1"
#define FILE_PATH2 "/mnt/UDISK/FILE_PATH2"
#define BUFFER_SIZE (1024 + 128)

off_t sw_get_file_size(const char *filename)
{
    if ((access(filename, F_OK)) == -1) {
        printf("%s is nothing", filename);
        return -1;
    }
    unsigned long filesize = -1;
    struct stat statbuff;
    if(stat(filename, &statbuff) < 0){
        return filesize;
    }else{
        filesize = statbuff.st_size;
    }
    printf("%s file size = %ld", filename, filesize);
    return filesize;
}

int main(int argc, char* argv[])
{
    int sockfd = -1;
    int ret = 0;
    int writelen = 0;
    FILE* file = NULL;
    const char* path;
    const char *filepath;
    char filepath1[128], filepath2[128];
    char buf[BUFFER_SIZE];
    struct sockaddr_un servaddr, cliaddr;

    if (argc < 2) {
        printf("Usage1: ./swlog " UNIXDG_PATH2 " /mnt/UDISK/signway_log\n");
        printf("Usage2: ./swlog " UNIXDG_PATH3 "\n");
        printf("Usage1: 打印并保存日志\n");
        printf("Usage2: 仅打印日志\n");
        return -1;
    }

    path = argv[1];
    printf("path[%s]\n", path);

    sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
    printf("socket = %d\n", sockfd);

    if ((access(path, F_OK)) != -1) {
        unlink(path);
        printf("unlink %s\n", path);
    }

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sun_family = AF_LOCAL;
    strcpy(servaddr.sun_path, path);

    ret = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    printf("ret[%d] %s bind ok\n", ret, servaddr.sun_path);

    socklen_t len = sizeof(struct sockaddr_un);

    if (strcmp(path, UNIXDG_PATH2) == 0) {
        snprintf(filepath1, sizeof(filepath1), "%s1.log", argv[2]);
        snprintf(filepath2, sizeof(filepath2), "%s2.log", argv[2]);
    }

    if (strcmp(path, UNIXDG_PATH2) == 0) {
        if ((access(FILE_PATH1, F_OK)) != -1) {
            file = fopen(filepath1, "a+");
            filepath = filepath1;
        }
        else if ((access(FILE_PATH2, F_OK)) != -1) {
            file = fopen(filepath2, "a+");
            filepath = filepath2;
        }
        else {
            file = fopen(filepath1, "a+");
            filepath = filepath1;
            system("touch " FILE_PATH1);
        }
        if (file == NULL) {
            perror("file failed!!!");
            goto RETURN;
        }
    }

    printf("start recv from...\n");
    while(1) {
        bzero(buf, BUFFER_SIZE);

        len = recvfrom(sockfd, buf, BUFFER_SIZE, 0, (struct sockaddr *)&cliaddr, &len);
        if (len == 0) {
            continue;
        }
        else if (len < 0) {
            perror("recvfrom");
        }

        if (strcmp(path, UNIXDG_PATH2) == 0) {
            writelen += fprintf(file, "%s", buf);
            if (writelen > 1024 * 1024) {
                writelen = 0;
                fflush(file);
                if (sw_get_file_size(filepath) >= 10 * 1024 * 1024) {
                    fclose(file);
                    if ((access(FILE_PATH1, F_OK)) != -1) {
                        system("rm " FILE_PATH1);	
                        system("touch " FILE_PATH2);
                        file = fopen(filepath2, "a+");
                        filepath = filepath2;
                    }
                    else {
                        system("rm " FILE_PATH2);	
                        system("touch " FILE_PATH1);
                        file = fopen(filepath1, "a+");
                        filepath = filepath1;
                    }
                    if (file == NULL) {
                        perror("file failed!!!!");
                        goto RETURN;
                    }
                }
            }
        }
        printf("%s", buf);
    }

RETURN:
    if (sockfd > 0)
        close(sockfd);
    if (file != NULL)
        fclose(file);
    if (path != NULL)
        unlink(path);
    return 0;
}
